<template>
  <div class="app-container">
    <header class="app-header">
      <h1>前端工程配置管理工具</h1>
    </header>

    <div class="main-content">
      <!-- 左侧配置文件列表 -->
      <div class="config-list">
        <h2>配置文件列表</h2>
        <div v-if="configFiles.length === 0" class="empty-tip">
          请先加载工程文件夹
        </div>
        <ul v-else>
          <li
            v-for="(file, index) in configFiles"
            :key="index"
            :class="{ active: selectedConfigIndex === index }"
            @click="selectConfig(index)"
          >
            {{ file.name }}
          </li>
        </ul>
        <div class="action-buttons">
          <button @click="loadProject" class="primary-button">
            加载工程文件夹
          </button>
        </div>
      </div>

      <!-- 右侧配置详情 -->
      <div class="config-details">
        <div v-if="!selectedConfig" class="empty-tip">
          请选择左侧配置文件查看详情
        </div>
        <div v-else>
          <div class="details-header">
            <h2>{{ selectedConfig.name }} 配置详情</h2>
            <div class="action-buttons">
              <button @click="saveConfig" class="primary-button">
                保存配置
              </button>
              <button @click="runProject" class="secondary-button">
                运行工程
              </button>
              <button @click="buildProject" class="secondary-button">
                构建工程
              </button>
            </div>
          </div>

          <!-- 公共配置项 -->
          <div class="config-section">
            <h3>公共配置项</h3>
            <div v-if="commonConfigs.length === 0" class="empty-tip">
              无公共配置项
            </div>
            <div v-else class="config-items">
              <div
                v-for="(item, key) in commonConfigs"
                :key="key"
                class="config-item"
              >
                <div class="item-key">{{ key }}:</div>
                <input
                  v-model="commonConfigs[key]"
                  class="item-value"
                  :title="commonConfigs[key]"
                />
              </div>
            </div>
          </div>

          <!-- 独有配置项 -->
          <div class="config-section">
            <h3>独有配置项</h3>
            <div
              v-if="Object.keys(uniqueConfigs).length === 0"
              class="empty-tip"
            >
              无独有配置项
            </div>
            <div v-else>
              <div
                v-for="(project, projectName) in uniqueConfigs"
                :key="projectName"
                class="project-unique-config"
              >
                <h4>{{ projectName }}</h4>
                <div class="config-items">
                  <div
                    v-for="(value, key) in project"
                    :key="key"
                    class="config-item"
                  >
                    <div class="item-key">{{ key }}:</div>
                    <input
                      v-model="uniqueConfigs[projectName][key]"
                      class="item-value"
                      :title="uniqueConfigs[projectName][key]"
                    />
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      projectPath: '',
      configFiles: [],
      selectedConfigIndex: -1,
      commonConfigs: {},
      uniqueConfigs: {},
    };
  },
  computed: {
    selectedConfig() {
      return this.selectedConfigIndex >= 0
        ? this.configFiles[this.selectedConfigIndex]
        : null;
    },
  },
  methods: {
    async loadProject() {
      try {
        // 打开文件夹选择对话框
        const selected = await window.__TAURI__.dialog.open({
          directory: true,
          multiple: false,
          title: '选择前端工程文件夹',
        });

        if (selected) {
          this.projectPath = selected;
          await this.scanConfigFiles();
        }
      } catch (error) {
        console.error('加载工程文件夹失败:', error);
        alert('加载工程文件夹失败: ' + error.message);
      }
    },

    async scanConfigFiles() {
      try {
        // 清空之前的配置文件
        this.configFiles = [];
        this.selectedConfigIndex = -1;

        // 读取工程目录结构
        const entries = await window.__TAURI__.fs.readDir(this.projectPath, {
          recursive: true,
        });

        // 查找所有可能的配置文件（如.env, config.js等）
        const configFileMap = {};

        const processEntry = (entry) => {
          if (entry.children) {
            entry.children.forEach(processEntry);
          } else {
            // 检查是否是配置文件
            const fileName = entry.name.toLowerCase();
            if (fileName.startsWith('.env')) {
              // 按文件名分组
              if (!configFileMap[entry.name]) {
                configFileMap[entry.name] = [];
              }
              configFileMap[entry.name].push({
                path: this.projectPath + '\\' + entry.name,
                projectName: this.getProjectName(
                  this.projectPath + '\\' + entry.name
                ),
              });
            }
          }
        };

        entries.forEach(processEntry);

        // 转换为配置文件列表
        for (const [name, files] of Object.entries(configFileMap)) {
          if (files.length > 0) {
            this.configFiles.push({
              name,
              files,
            });
          }
        }

        console.log('找到配置文件:', this.configFiles);
      } catch (error) {
        console.error('扫描配置文件失败:', error);
        alert('扫描配置文件失败: ' + error.message);
      }
    },

    getProjectName(filePath) {
      // 从文件路径中提取项目名称
      const parts = filePath.replace(this.projectPath, '').split(/[\\/]/);
      return parts[1] || '根目录';
    },

    async selectConfig(index) {
      this.selectedConfigIndex = index;
      await this.loadConfigDetails();
    },

    async loadConfigDetails() {
      if (!this.selectedConfig) return;

      try {
        const config = this.selectedConfig;
        const configContents = {};
        console.log(config, 'config');
        // 读取所有相关配置文件的内容
        for (const file of config.files) {
          const content = await window.__TAURI__.fs.readTextFile(file.path);
          configContents[file.projectName] = this.parseConfigContent(
            file.path,
            content
          );
        }

        // 分析公共配置和独有配置
        this.analyzeConfigs(configContents);
      } catch (error) {
        console.error('加载配置详情失败:', error);
        alert('加载配置详情失败: ' + error.message);
      }
    },

    parseConfigContent(filePath, content) {
      // 根据文件类型解析配置内容
      try {
        if (filePath.endsWith('.json')) {
          return JSON.parse(content);
        } else if (
          filePath.endsWith('.js') ||
          filePath.endsWith('.cjs') ||
          filePath.endsWith('.mjs')
        ) {
          // 简单处理JS配置文件，实际项目中可能需要更复杂的解析
          // 这里只是一个简化示例
          const configObj = {};
          const lines = content.split('\n');

          for (const line of lines) {
            const match = line.match(
              /['"]?([\w.]+)['"]?\s*:\s*['"]?([^'"\s,]+)['"]?/g
            );
            if (match) {
              match.forEach((item) => {
                const [key, value] = item
                  .split(':')
                  .map((s) => s.trim().replace(/['",]/g, ''));
                configObj[key] = value;
              });
            }
          }

          return configObj;
        } else if (filePath.includes('.env')) {
          // 解析.env文件
          const configObj = {};
          const lines = content.split('\n');

          for (const line of lines) {
            if (line.trim() && !line.startsWith('#')) {
              const [key, ...valueParts] = line.split('=');
              const value = valueParts.join('=');
              if (key && value) {
                configObj[key.trim()] = value.trim();
              }
            }
          }

          return configObj;
        }

        // 默认返回空对象
        return {};
      } catch (error) {
        console.error('解析配置文件失败:', error);
        return {};
      }
    },

    analyzeConfigs(configContents) {
      // 重置配置
      this.commonConfigs = {};
      this.uniqueConfigs = {};

      if (Object.keys(configContents).length === 0) return;

      // 如果只有一个项目，所有配置都是独有的
      if (Object.keys(configContents).length === 1) {
        const projectName = Object.keys(configContents)[0];
        this.uniqueConfigs[projectName] = configContents[projectName];
        return;
      }

      // 分析多个项目的配置
      const allKeys = new Set();
      const keyCount = {};

      // 收集所有键并计数
      for (const [projectName, config] of Object.entries(configContents)) {
        for (const key of Object.keys(config)) {
          allKeys.add(key);
          keyCount[key] = (keyCount[key] || 0) + 1;
        }
      }

      const projectCount = Object.keys(configContents).length;

      // 分类公共配置和独有配置
      for (const key of allKeys) {
        // 如果一个键在所有项目中都存在，则认为是公共配置
        if (keyCount[key] === projectCount) {
          // 检查值是否相同
          const values = new Set();
          for (const config of Object.values(configContents)) {
            values.add(JSON.stringify(config[key]));
          }

          // 如果所有项目的值都相同，则是公共配置
          if (values.size === 1) {
            this.commonConfigs[key] = Object.values(configContents)[0][key];
          } else {
            // 值不同，作为独有配置
            for (const [projectName, config] of Object.entries(
              configContents
            )) {
              if (!this.uniqueConfigs[projectName]) {
                this.uniqueConfigs[projectName] = {};
              }
              this.uniqueConfigs[projectName][key] = config[key];
            }
          }
        } else {
          // 不是所有项目都有的键，作为独有配置
          for (const [projectName, config] of Object.entries(configContents)) {
            if (config[key] !== undefined) {
              if (!this.uniqueConfigs[projectName]) {
                this.uniqueConfigs[projectName] = {};
              }
              this.uniqueConfigs[projectName][key] = config[key];
            }
          }
        }
      }
    },

    async saveConfig() {
      if (!this.selectedConfig) return;

      try {
        // 合并配置并保存到各个项目
        for (const file of this.selectedConfig.files) {
          const projectName = file.projectName;
          const originalContent = await window.__TAURI__.fs.readTextFile(
            file.path
          );

          // 创建新的配置对象
          let newConfig = { ...this.commonConfigs };

          // 添加该项目的独有配置
          if (this.uniqueConfigs[projectName]) {
            Object.assign(newConfig, this.uniqueConfigs[projectName]);
          }

          // 根据文件类型生成新的配置内容
          let newContent = this.generateConfigContent(
            file.path,
            originalContent,
            newConfig
          );

          // 写入文件
          await window.__TAURI__.fs.writeTextFile(file.path, newContent);
        }

        alert('配置保存成功！');
      } catch (error) {
        console.error('保存配置失败:', error);
        alert('保存配置失败: ' + error.message);
      }
    },

    generateConfigContent(filePath, originalContent, newConfig) {
      // 根据文件类型生成新的配置内容
      if (filePath.endsWith('.json')) {
        return JSON.stringify(newConfig, null, 2);
      } else if (filePath.includes('.env')) {
        // 生成.env格式
        return Object.entries(newConfig)
          .map(([key, value]) => `${key}=${value}`)
          .join('\n');
      } else if (
        filePath.endsWith('.js') ||
        filePath.endsWith('.cjs') ||
        filePath.endsWith('.mjs')
      ) {
        // 简单处理JS配置文件，保留原始结构
        // 这是一个简化实现，实际项目中可能需要更复杂的处理
        let content = originalContent;

        for (const [key, value] of Object.entries(newConfig)) {
          const valueStr = typeof value === 'string' ? `'${value}'` : value;
          const regex = new RegExp(`(['"]?${key}['"]?\s*:\s*)[^,\n}]*`);

          if (content.match(regex)) {
            // 替换现有值
            content = content.replace(regex, `$1${valueStr}`);
          } else {
            // 添加新键值对
            // 查找最后一个属性
            const lastPropIndex = content.lastIndexOf('}');
            if (lastPropIndex !== -1) {
              content =
                content.slice(0, lastPropIndex) +
                `  ${key}: ${valueStr},\n` +
                content.slice(lastPropIndex);
            }
          }
        }

        return content;
      }

      // 默认返回原始内容
      return originalContent;
    },

    async runProject() {
      if (!this.selectedConfig) return;

      try {
        // 选择要运行的项目
        const projectOptions = this.selectedConfig.files.map(
          (file) => file.projectName
        );
        const selectedProject = await this.showProjectSelector(
          '选择要运行的项目',
          projectOptions
        );

        if (!selectedProject) return;

        // 找到对应的项目路径
        const projectFile = this.selectedConfig.files.find(
          (file) => file.projectName === selectedProject
        );
        if (!projectFile) return;

        const projectPath = projectFile.path.substring(
          0,
          projectFile.path.lastIndexOf('\\')
        );

        // 执行npm run dev命令
        const command = new window.__TAURI__.shell.Command(
          'npm',
          ['run', 'dev'],
          {
            cwd: projectPath,
          }
        );
        command.on('close', (data) => {
          console.log('命令执行完成，退出码:', data.code);
        });
        command.on('error', (error) => {
          console.error('命令执行错误:', error);
          alert('运行项目失败: ' + error);
        });
        command.stdout.on('data', (line) => console.log('stdout:', line));
        command.stderr.on('data', (line) => console.error('stderr:', line));

        const child = await command.spawn();
        console.log('正在运行项目，进程ID:', child.pid);
        alert(`正在运行项目: ${selectedProject}`);
      } catch (error) {
        console.error('运行项目失败:', error);
        alert('运行项目失败: ' + error.message);
      }
    },

    async buildProject() {
      if (!this.selectedConfig) return;

      try {
        // 选择要构建的项目
        const projectOptions = this.selectedConfig.files.map(
          (file) => file.projectName
        );
        const selectedProject = await this.showProjectSelector(
          '选择要构建的项目',
          projectOptions
        );

        if (!selectedProject) return;

        // 找到对应的项目路径
        const projectFile = this.selectedConfig.files.find(
          (file) => file.projectName === selectedProject
        );
        if (!projectFile) return;

        const projectPath = projectFile.path.substring(
          0,
          projectFile.path.lastIndexOf('\\')
        );

        // 执行npm run build命令
        const command = new window.__TAURI__.shell.Command(
          'npm',
          ['run', 'build'],
          {
            cwd: projectPath,
          }
        );
        command.on('close', (data) => {
          console.log('命令执行完成，退出码:', data.code);
          if (data.code === 0) {
            alert(`项目构建成功: ${selectedProject}`);
          } else {
            alert(`项目构建失败，退出码: ${data.code}`);
          }
        });
        command.on('error', (error) => {
          console.error('命令执行错误:', error);
          alert('构建项目失败: ' + error);
        });
        command.stdout.on('data', (line) => console.log('stdout:', line));
        command.stderr.on('data', (line) => console.error('stderr:', line));

        const child = await command.spawn();
        console.log('正在构建项目，进程ID:', child.pid);
        alert(`正在构建项目: ${selectedProject}`);
      } catch (error) {
        console.error('构建项目失败:', error);
        alert('构建项目失败: ' + error.message);
      }
    },

    async showProjectSelector(title, options) {
      // 简单的项目选择器实现
      // 在实际应用中，可以使用更好的UI组件
      return prompt(title + '\n\n可选项目: ' + options.join(', '), options[0]);
    },
  },
};
</script>

<style>
.app-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

.app-header {
  background-color: #2c3e50;
  color: white;
  padding: 1rem;
  text-align: center;
}

.main-content {
  display: flex;
  flex: 1;
  overflow: hidden;
}

.config-list {
  width: 250px;
  border-right: 1px solid #ddd;
  padding: 1rem;
  overflow-y: auto;
  background-color: #f5f5f5;
}

.config-list ul {
  list-style: none;
  padding: 0;
  margin: 1rem 0;
}

.config-list li {
  padding: 0.5rem;
  margin-bottom: 0.5rem;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.config-list li:hover {
  background-color: #e0e0e0;
}

.config-list li.active {
  background-color: #4c6ef5;
  color: white;
}

.config-details {
  flex: 1;
  padding: 1rem;
  overflow-y: auto;
}

.details-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid #ddd;
}

.config-section {
  margin-bottom: 2rem;
}

.config-items {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem;
}

.config-item {
  display: flex;
  align-items: center;
  padding: 0.5rem;
  border-radius: 4px;
  background-color: #f9f9f9;
}

.item-key {
  width: 350px;
  font-weight: bold;
  overflow: hidden;
  text-overflow: ellipsis;
}

.item-value {
  flex: 1;
  padding: 0.5rem;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.project-unique-config {
  margin-bottom: 1.5rem;
  padding: 1rem;
  border-radius: 4px;
  background-color: #f0f4f8;
}

.action-buttons {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
}

.primary-button {
  background-color: #4c6ef5;
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.primary-button:hover {
  background-color: #3b5bdb;
}

.secondary-button {
  background-color: #868e96;
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.secondary-button:hover {
  background-color: #495057;
}

.empty-tip {
  padding: 1rem;
  text-align: center;
  color: #868e96;
  font-style: italic;
  background-color: #f8f9fa;
  border-radius: 4px;
  margin: 1rem 0;
}
</style>
